home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / arpcmd.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  9KB  |  388 lines

  1. /* ARP commands
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  *
  6.  * Mods by SM6RPZ
  7.  * 1992-05-28 - Added interface to "arp add ..."-command.
  8.  * 1992-07-26 - Small cosmetic changes here and there.
  9.  */
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include "global.h"
  13. #include "config.h"
  14. #include "mbuf.h"
  15. #include "timer.h"
  16. #include "internet.h"
  17. #include "ip.h"
  18. #ifdef ETHER
  19. #include "enet.h"
  20. #endif
  21. #include "ax25.h"
  22. #include "arp.h"
  23. #include "netuser.h"
  24. #include "cmdparse.h"
  25. #include "commands.h"
  26. #include "iface.h"
  27. #include "rspf.h"
  28. #include "socket.h"
  29. #include "domain.h"
  30. #include "session.h"
  31.  
  32. int Arp_Sort=1;  /* set Initial sort mode */
  33.  
  34. static int doarpsort __ARGS((int argc,char *argv[],void *p));
  35. static void make_arp_string __ARGS((struct arp_tab *ap,char *buf));
  36. static int doarpadd __ARGS((int argc,char *argv[],void *p));
  37. static int doarpdrop __ARGS((int argc,char *argv[],void *p));
  38. static int doarpflush __ARGS((int argc,char *argv[],void *p));
  39. static int doarppoll __ARGS((int argc,char *argv[],void *p));
  40. static int doarpeaves __ARGS((int argc,char *argv[],void *p));
  41. static int doarpqueue __ARGS((int argc,char *argv[],void *p));
  42. static void dumparp __ARGS((void));
  43.  
  44. static struct cmds Arpcmds[] = {
  45.     "add", doarpadd, 0, 4,
  46.     "arp add <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>",
  47.  
  48.     "drop", doarpdrop, 0, 3,
  49.     "arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>",
  50.  
  51.     "eaves", doarpeaves, 0, 0, NULLCHAR,
  52.  
  53.     "flush", doarpflush, 0, 0,
  54.     NULLCHAR,
  55.  
  56.     "maxq", doarpqueue, 0, 0, NULLCHAR,
  57.  
  58.     "poll", doarppoll, 0, 0, NULLCHAR,
  59.  
  60.     "publish", doarpadd, 0, 4,
  61.     "arp publish <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>",
  62.  
  63.     "sort",    doarpsort, 0, 0,
  64.     NULLCHAR,
  65.  
  66.     NULLCHAR,
  67. };
  68.  
  69. char *Arptypes[] = {
  70.     "NET/ROM",
  71.     "10 Mb Ethernet",
  72.     "3 Mb Ethernet",
  73.     "AX.25",
  74.     "Pronet",
  75.     "Chaos",
  76.     "",
  77.     "Arcnet",
  78.     "Appletalk"
  79. };
  80.  
  81. int
  82. doarp(argc,argv,p)
  83. int argc;
  84. char *argv[];
  85. void *p;
  86. {
  87.     if(argc < 2){
  88.         dumparp();
  89.         return 0;
  90.     }
  91.     return subcmd(Arpcmds,argc,argv,p);
  92. }
  93.  
  94. static int
  95. doarpadd(argc,argv,p)
  96. int argc;
  97. char *argv[];
  98. void *p;
  99. {
  100.     int16 hardware;
  101.     int32 addr;
  102.     char *hwaddr;
  103.     struct arp_tab *ap;
  104.     struct arp_type *at;
  105.     int pub = 0;
  106.     struct iface *iface;
  107.  
  108.     if(argv[0][0] == 'p')   /* Is this entry published? */
  109.         pub = 1;
  110.     if((addr = resolve(argv[1])) == 0){
  111.         tprintf(Badhost,argv[1]);
  112.         return 1;
  113.     }
  114.     if(argc == 4 && tolower(argv[2][0]) != 'n') {
  115.         tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  116.         pub ? "publish" : "add");
  117.         return -1;
  118.     }
  119.     /* This is a kludge. It really ought to be table driven */
  120.     switch(tolower(argv[2][0])){
  121.     case 'n':       /* Net/Rom pseudo-type */
  122.         argc = 5;
  123.         argv[4] = "netrom";     /* Force use of netrom interface */
  124.         hardware = ARP_NETROM;
  125.         break;
  126.     case 'e':       /* "ether" */
  127.         hardware = ARP_ETHER;
  128.         break;          
  129.     case 'a':       /* "ax25" */
  130.         switch(tolower(argv[2][1])) {
  131.         case 'x':
  132.             hardware = ARP_AX25;
  133.             break;
  134.         case 'r':
  135.             hardware = ARP_ARCNET;
  136.             break;
  137.         default:
  138.             tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  139.                 pub ? "publish" : "add");
  140.             return -1;
  141.         }
  142.         break;
  143.     case 'm':       /* "mac appletalk" */
  144.         hardware = ARP_APPLETALK;
  145.         break;
  146.     default:
  147.         tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  148.             pub ? "publish" : "add");
  149.         return -1;
  150.     }
  151.     if((iface = if_lookup(argv[4])) == NULLIF) {
  152.         tprintf("No such interface %s\n", argv[4]);
  153.         return 1;
  154.     }
  155.     /* If an entry already exists, clear it */
  156.     if((ap = arp_lookup(hardware,addr,iface)) != NULLARP)
  157.         arp_drop(ap);
  158.  
  159.     at = &Arp_type[hardware];
  160.     if(at->scan == NULLFP((char*,char*))){
  161.         tputs("Attach device first\n");
  162.         return 1;
  163.     }
  164.     /* Allocate buffer for hardware address and fill with remaining args */
  165.     hwaddr = mallocw((unsigned)at->hwalen);
  166.     /* Destination address */
  167.     (*at->scan)(hwaddr,argv[3]);
  168.     ap = arp_add(addr,hardware,hwaddr,pub,iface);   /* Put in table */
  169.     free(hwaddr);                                   /* Clean up */
  170.     stop_timer(&ap->timer);                     /* Make entry permanent */
  171.     set_timer(&ap->timer,0L);
  172. #ifdef  RSPF
  173.     rspfarpupcall(addr,hardware,NULLIF);  /* Do a RSPF upcall */
  174. #endif  /* RSPF */
  175.     return 0;
  176. }
  177.  
  178. static int
  179. doarpeaves(argc,argv,p)
  180. int argc ;
  181. char *argv[] ;
  182. void *p;
  183. {
  184.     return setflag(argc,argv[1],ARP_EAVESDROP,argv[2]);
  185. }
  186.  
  187. static int
  188. doarppoll(argc,argv,p)
  189. int argc ;
  190. char *argv[] ;
  191. void *p;
  192. {
  193.     return setflag(argc,argv[1],ARP_KEEPALIVE,argv[2]);
  194. }
  195.  
  196. int Maxarpq = 5;
  197.  
  198. static int
  199. doarpqueue(argc,argv,p)
  200. int argc ;
  201. char *argv[] ;
  202. void *p;
  203. {
  204.     return setint(&Maxarpq,"Max queue",argc,argv);
  205. }
  206.  
  207.  
  208. /* Remove an ARP entry */
  209. static int
  210. doarpdrop(argc,argv,p)
  211. int argc;
  212. char *argv[];
  213. void *p;
  214. {
  215.     int16 hardware;
  216.     int32 addr;
  217.     struct arp_tab *ap;
  218.     struct iface *iface;
  219.  
  220.     if((addr = resolve(argv[1])) == 0){
  221.         tprintf(Badhost,argv[1]);
  222.         return 1;
  223.     }
  224.     if(argc == 3 && tolower(argv[2][0]) != 'n') {
  225.         tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  226.         return -1;
  227.     }
  228.     /* This is a kludge. It really ought to be table driven */
  229.     switch(tolower(argv[2][0])){
  230.     case 'n':
  231.         argc = 4;
  232.         argv[3] = "netrom";     /* Force use of netrom interface */
  233.         hardware = ARP_NETROM;
  234.         break;
  235.     case 'e':       /* "ether" */
  236.         hardware = ARP_ETHER;
  237.         break;          
  238.     case 'a':       /* "ax25" */
  239.         switch(tolower(argv[2][1])) {
  240.         case 'x':
  241.             hardware = ARP_AX25;
  242.             break;
  243.         case 'r':
  244.             hardware = ARP_ARCNET;
  245.             break;
  246.         default:
  247.             tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  248.             return -1;
  249.         }
  250.         break;
  251.     case 'm':       /* "mac appletalk" */
  252.         hardware = ARP_APPLETALK;
  253.         break;
  254.     default:
  255.         tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  256.         return -1;
  257.     }
  258.     if((iface = if_lookup(argv[3])) == NULLIF) {
  259.         tprintf("No such interface %s\n", argv[3]);
  260.         return 1;
  261.     }
  262.     if((ap = arp_lookup(hardware,addr,iface)) == NULLARP)
  263.         return -1;
  264.     arp_drop(ap);
  265.     return 0;       
  266. }
  267.  
  268. /* Flush all automatic entries in the arp cache */
  269. static int
  270. doarpflush(argc,argv,p)
  271. int argc;
  272. char *argv[];
  273. void *p;
  274. {
  275.     register struct arp_tab *ap;
  276.     struct arp_tab *aptmp;
  277.     int i;
  278.  
  279.     for(i=0;i<HASHMOD;i++){
  280.         for(ap = Arp_tab[i];ap != NULLARP;ap = aptmp){
  281.             aptmp = ap->next;
  282.             if(dur_timer(&ap->timer) != 0)
  283.                 arp_drop(ap);
  284.         }
  285.     }
  286.     return 0;
  287. }
  288.  
  289. /* Dump ARP table */
  290. static void
  291. dumparp()
  292. {
  293.     register int i,j,k,flow_tmp;
  294.     register struct arp_tab *ap;
  295.     char *temp;        
  296.     
  297.     flow_tmp=Current->flowmode;
  298.     Current->flowmode=1;
  299.  
  300.     tprintf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
  301.      Arp_stat.recv,Arp_stat.badtype,Arp_stat.badaddr,Arp_stat.inreq,
  302.      Arp_stat.replies,Arp_stat.outreq);
  303.  
  304.     for(i=0,j=0;i<HASHMOD;i++)
  305.        for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next,j++);
  306.     
  307.     if (j) {
  308.  
  309.       tprintf("IP addr         Type           Time Q Address           Interface\n");
  310.     
  311.       temp=mallocw((unsigned)j*80);
  312.     
  313.       for(i=0,k=0;i<HASHMOD;i++) {
  314.          for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next,k+=80)
  315.         make_arp_string(ap,&temp[k]);
  316.       }
  317.  
  318.       if (Arp_Sort) qsort(temp,(size_t)j,80,(int (*)__FARGS((const void*,const void*))) strcmp);
  319.  
  320.       for(i=0,k=4;i<j;i++,k+=80) {
  321.           tprintf("%s",&temp[k]);
  322.           if(tprintf("\n") == EOF)  break;
  323.       }
  324.       free(temp);
  325.     }
  326.  
  327.     Current->flowmode=flow_tmp;
  328. }
  329.  
  330. void
  331. make_arp_string(ap,buf)
  332. register struct arp_tab *ap;
  333. char *buf;
  334. {
  335.     char e[128];
  336.     unsigned a=0;
  337.     char *name;
  338.  
  339.     if(DTranslate && (name = resolve_a(ap->ip_addr,!DVerbose)) != NULLCHAR) {
  340.     strcpy(buf, name);
  341.     a+=4;
  342.     free(name);
  343.     } else {
  344.     a=sprintf(buf,"%4.4s",inet_ntobos(ap->ip_addr));
  345.     }
  346.  
  347.     a+=sprintf(&buf[a],"%-15.15s ",inet_ntoa(ap->ip_addr));
  348.     a+=sprintf(&buf[a],"%-14.14s ",smsg(Arptypes,NHWTYPES,(unsigned)ap->hardware));
  349.     a+=sprintf(&buf[a],"%4ld ",read_timer(&ap->timer)/1000L);
  350.  
  351.     if(ap->state == ARP_PENDING)
  352.     a+=sprintf(&buf[a],"%1.1u ",len_q(ap->pending));
  353.     else
  354.     a+=sprintf(&buf[a],"  ");
  355.  
  356.     if(ap->state == ARP_VALID){
  357.     if(Arp_type[ap->hardware].format != NULL){
  358.         (*Arp_type[ap->hardware].format)(e,ap->hw_addr);
  359.        } else {
  360.         e[0]='\0';
  361.        }
  362.        a+=sprintf(&buf[a],"%-17.17s ",e);
  363.     } else {
  364.        a+=sprintf(&buf[a],"[unknown]         ");
  365.     }
  366.  
  367.     if (ap->iface)
  368.     a+=sprintf(&buf[a],"%-6.6s ",ap->iface->name);
  369.  
  370.     if(ap->pub)
  371.     a+=sprintf(&buf[a],"(published)");
  372.  
  373.     return;
  374. }
  375.  
  376. /* Sort ARP dump */
  377. static int
  378. doarpsort(argc,argv,p)
  379. int argc ;
  380. char *argv[] ;
  381. void *p;
  382. {
  383.     extern int Arp_Sort;
  384.  
  385.     return setbool(&Arp_Sort,"ARP Sort flag",argc,argv);
  386. }
  387.  
  388.